<?php
/**
 * Class TravelPhysAjax
 * @version 1.2.5
 * @author  physcode
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class TravelPhysAjax {
	public $_is_tour_variation = false;
	public static $_set_price_tour_only_one = true;

	public static function init() {
		if ( is_admin() ) {
			// ajax backend
			add_action( 'wp_print_scripts', array( __CLASS__, 'tour_booking_phys_ajax_url' ), 11 );
		} else {
			// ajax frontend
			add_action( 'template_redirect', array( __CLASS__, 'do_tb_ajax' ), 11 );
			add_action( 'tb_ajax_add_tour_to_cart_phys', array( __CLASS__, 'add_tour_to_cart_phys' ) );
			add_action( 'woocommerce_before_calculate_totals', array( __CLASS__, 'set_regular_price_tour_phys' ) );
			add_action( 'woocommerce_after_calculate_totals', array( __CLASS__, 'update_price_for_tour' ), 20 );
			add_filter( 'woocommerce_cart_item_subtotal', array( __CLASS__, 'update_subtotal' ), 10, 2 );
		}
	}

	public static function tour_booking_phys_ajax_url() {
		if ( is_plugin_active( 'polylang/polylang.php' ) ) {
			$optional     = 'slug';
			$current_lang = pll_current_language( $optional );

			echo '<script type="text/javascript">';
			echo 'var tb_phys_ajax_url = "' . get_site_url() . '/' . $current_lang . '/"';
			echo '</script>';
		} else {
			echo '<script type="text/javascript">
		var tb_phys_ajax_url ="' . get_site_url() . '/";
		</script>';
		}
	}

	public static function do_tb_ajax() {
		global $wp_query;
		if ( ! empty( $_GET['tb-ajax'] ) ) {
			$wp_query->set( 'tb-ajax', sanitize_text_field( $_GET['tb-ajax'] ) );
		}

		if ( $action = $wp_query->get( 'tb-ajax' ) ) {
			do_action( 'tb_ajax_' . sanitize_text_field( $action ) );
			die();
		}
	}

	public static function add_tour_to_cart_phys() {
		$message = array( 'status' => 'error', 'message' => '' );
		//	if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'tb_booking_nonce_action' ) ) {
		//$date_now = date( 'Y-m-d' );

		if ( ! isset( $_POST['tour_id'] ) ) {
			$message['message'] = 'invalid tour';
			wp_send_json( $message );
		}

		do_action( 'woocommerce_set_cart_cookies', true );

		$show_date_book = apply_filters( 'tb_show_date_book', true );

		$tour_id   = (int) $_POST['tour_id'];
		$cart_tour = WC()->cart;
		//		$now             = strtotime( date( 'Y-m-d H:i:s.u' ) );
		$basket_item_key = $cart_tour->generate_cart_id( $tour_id );
		$tour            = wc_get_product( $tour_id );

		$cart_tour->cart_contents[$basket_item_key] = array(
			'product_id'   => $tour_id,
			'is_tour'      => true,
			'variation_id' => 0,
			'variation'    => 0,
			'data'         => $tour,
			'currency'     => get_woocommerce_currency_symbol( get_woocommerce_currency() )
		);

		if ( $show_date_book ) {
			if ( isset( $_POST['date_booking'] ) ) {
				$date_format_config                                         = get_option( 'date_format_tour', TravelPhysUtility::$_date_format_default );
				$cart_tour->cart_contents[$basket_item_key]['date_booking'] = $_POST['date_booking'];
				$duration_number                                            = (int) get_post_meta( $tour_id, '_phys_tour_duration_number', true ) - 1;

				if ( $duration_number < 0 ) {
					$duration_number = 0;
				}

				$date_book_format_date_default = TravelPhysUtility::convert_date_to_format_default( $_POST['date_booking'] );
				$date_book_obj                 = new DateTime( $date_book_format_date_default );
				$date_end_obj                  = $date_book_obj->add( new DateInterval( 'P' . $duration_number . 'D' ) );

				$cart_tour->cart_contents[$basket_item_key]['tour_date_end'] = $date_end_obj->format( $date_format_config );
			} else {
				if ( isset( $_POST['date_check_in'] ) ) {
					$cart_tour->cart_contents[$basket_item_key]['date_check_in'] = $_POST['date_check_in'];
				} else {
					$message['message'] = 'invalid date check in';
					wp_send_json( $message );
				}

				if ( isset( $_POST['date_check_out'] ) ) {
					$cart_tour->cart_contents[$basket_item_key]['date_check_out'] = $_POST['date_check_out'];
				} else {
					$message['message'] = 'invalid date check out';
					wp_send_json( $message );
				}
			}
		}

		if ( isset( $_POST['number_ticket'] ) ) {
			$number_ticket          = (int) $_POST['number_ticket'] > 0 ? $_POST['number_ticket'] : 1;
			$tour_number_ticket_max = (int) get_post_meta( $tour_id, '_tour_max_number_ticket_per_booking', true );

			if ( $number_ticket > $tour_number_ticket_max && $tour_number_ticket_max > 0 ) {
				$number_ticket = $tour_number_ticket_max;
			}

			$cart_tour->cart_contents[$basket_item_key]['quantity'] = $number_ticket;
		}

		if ( isset( $_POST['number_children'] ) ) {
			$number_children = (int) $_POST['number_children'] > 0 ? (int) $_POST['number_children'] : 0;

			$cart_tour->cart_contents[$basket_item_key]['number_children'] = $number_children;
			$price_children                                                = Phys_Cart_Totals::get_price_child_tour( $cart_tour->cart_contents[$basket_item_key] );
			$cart_tour->cart_contents[$basket_item_key]['price_children']  = $price_children;
		}

		// Variations
		if ( isset( $_POST['tour_variations'] ) ) {
			try {
				$cart_tour->cart_contents[$basket_item_key]['tour_variations']         = json_decode( str_replace( '\\', '', $_POST['tour_variations'] ) );
				$cart_tour->cart_contents[$basket_item_key]['tour_variations_options'] = json_decode( get_post_meta( $tour_id, '_tour_variations_options', true ) );
			}
			catch ( Exception $e ) {
				wp_send_json( $e );
			}
		}

		// Price dates tour
		$cart_tour->cart_contents[$basket_item_key]['price_dates_tour'] = Phys_Cart_Totals::get_price_dates_tour( $cart_tour->cart_contents[$basket_item_key] );

		$cart_tour->calculate_totals();

		$message['status'] = 'success';
		//	}
		wp_send_json( $message );
	}

	public static function set_regular_price_tour_phys( $cart_object ) {
		if ( self::$_set_price_tour_only_one ) {
			self::$_set_price_tour_only_one = false;

			foreach ( $cart_object->cart_contents as $key => $cart_item ) {

				$price_dates_tour = new stdClass();

				if ( array_key_exists( 'price_dates_tour', $cart_item ) ) {
					$price_dates_tour = $cart_item['price_dates_tour'];

					if ( isset( $price_dates_tour->regular_price_dates ) ) {
						$cart_item['data']->set_price( $price_dates_tour->regular_price_dates );
						$cart_object->cart_contents[$key]['data']->set_price( $price_dates_tour->regular_price_dates );
					}
				}
			}
		}
	}

	public static function update_price_for_tour( $cart_object ) {
		if ( TravelBookingPhyscode::$_version_woo < 3.2 ) {
			foreach ( $cart_object->cart_session_data as $key => $default ) {
				$cart_object->$key = $default;
			}
			do_action( 'woocommerce_cart_reset', $cart_object, false );

			$cart_object->coupons = $cart_object->get_coupons();

			if ( $cart_object->is_empty() ) {
				$cart_object->set_session();

				return;
			}

			$tax_rates      = array();
			$shop_tax_rates = array();
			$cart           = $cart_object->get_cart();

			/**
			 * Calculate subtotals for items. This is done first so that discount logic can use the values.
			 */
			foreach ( $cart as $cart_item_key => $values ) {
				$_product = $values['data'];

				/** Update number child if update cart **/
				if ( isset( $_POST['cart'] ) ) {
					if ( isset( $values['number_children'] ) ) {
						$cart[$cart_item_key]['number_children']                       = $_POST['cart'][$cart_item_key]['number_children'];
						$cart_object->cart_contents[$cart_item_key]['number_children'] = $_POST['cart'][$cart_item_key]['number_children'];
					}
				}

				if ( isset( $values['number_children'] ) ) {
					$line_price_child = Phys_Cart_Totals::get_price_for_child_on_tour( $_product, $values['date_booking'] );
					$line_price       = $_product->get_price() * $values['quantity'] + $line_price_child * $values['number_children'];

					// set for order info
					$cart_object->cart_contents[$cart_item_key]['price_adults']   = $_product->get_price();
					$cart_object->cart_contents[$cart_item_key]['price_children'] = $line_price_child;
				} else {
					$line_price = $_product->get_price() * $values['quantity'];
				}
				$line_subtotal     = 0;
				$line_subtotal_tax = 0;

				/**
				 * No tax to calculate.
				 */
				if ( ! $_product->is_taxable() ) {

					// Subtotal is the undiscounted price
					$cart_object->subtotal        += $line_price;
					$cart_object->subtotal_ex_tax += $line_price;

					/**
					 * Prices include tax.
					 *
					 * To prevent rounding issues we need to work with the inclusive price where possible.
					 * otherwise we'll see errors such as when working with a 9.99 inc price, 20% VAT which would.
					 * be 8.325 leading to totals being 1p off.
					 *
					 * Pre tax coupons come off the price the customer thinks they are paying - tax is calculated.
					 * afterwards.
					 *
					 * e.g. $100 bike with $10 coupon = customer pays $90 and tax worked backwards from that.
					 */
				} elseif ( $cart_object->prices_include_tax ) {

					// Get base tax rates
					if ( empty( $shop_tax_rates[$_product->tax_class] ) ) {
						$shop_tax_rates[$_product->tax_class] = WC_Tax::get_base_tax_rates( $_product->tax_class );
					}

					// Get item tax rates
					if ( empty( $tax_rates[$_product->get_tax_class()] ) ) {
						$tax_rates[$_product->get_tax_class()] = WC_Tax::get_rates( $_product->get_tax_class() );
					}

					$base_tax_rates = $shop_tax_rates[$_product->tax_class];
					$item_tax_rates = $tax_rates[$_product->get_tax_class()];

					/**
					 * ADJUST TAX - Calculations when base tax is not equal to the item tax.
					 *
					 * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing with out of base locations.
					 * e.g. If a product costs 10 including tax, all users will pay 10 regardless of location and taxes.
					 * This feature is experimental @since 2.4.7 and may change in the future. Use at your risk.
					 */
					if ( $item_tax_rates !== $base_tax_rates && apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ) {

						// Work out a new base price without the shop's base tax
						$taxes = WC_Tax::calc_tax( $line_price, $base_tax_rates, true, true );

						// Now we have a new item price (excluding TAX)
						$line_subtotal = $line_price - array_sum( $taxes );

						// Now add modified taxes
						$tax_result        = WC_Tax::calc_tax( $line_subtotal, $item_tax_rates );
						$line_subtotal_tax = array_sum( $tax_result );

						/**
						 * Regular tax calculation (customer inside base and the tax class is unmodified.
						 */
					} else {

						// Calc tax normally
						$taxes             = WC_Tax::calc_tax( $line_price, $item_tax_rates, true );
						$line_subtotal_tax = array_sum( $taxes );
						$line_subtotal     = $line_price - array_sum( $taxes );
					}

					/**
					 * Prices exclude tax.
					 *
					 * This calculation is simpler - work with the base, untaxed price.
					 */
				} else {

					// Get item tax rates
					if ( empty( $tax_rates[$_product->get_tax_class()] ) ) {
						$tax_rates[$_product->get_tax_class()] = WC_Tax::get_rates( $_product->get_tax_class() );
					}

					$item_tax_rates = $tax_rates[$_product->get_tax_class()];

					// Base tax for line before discount - we will store this in the order data
					$taxes             = WC_Tax::calc_tax( $line_price, $item_tax_rates );
					$line_subtotal_tax = array_sum( $taxes );

					$line_subtotal = $line_price;
				}

				// Add to main subtotal
				$cart_object->subtotal += $line_subtotal + $line_subtotal_tax;;
				$cart_object->subtotal_ex_tax += $line_subtotal;
			}

			// Order cart items by price so coupon logic is 'fair' for customers and not based on order added to cart.
			//	uasort( $cart, array( $cart_object, 'sort_by_subtotal' ) );

			/**
			 * Calculate totals for items.
			 */
			foreach ( $cart as $cart_item_key => $values ) {

				$_product = $values['data'];
				// Prices
				if ( isset( $values['number_children'] ) ) {
					$line_price_child = Phys_Cart_Totals::get_price_for_child_on_tour( $_product, $values['date_booking'] );

					$base_price = $_product->get_price() * $values['quantity'] + $line_price_child * $values['number_children'];
					$line_price = $_product->get_price() * $values['quantity'] + $line_price_child * $values['number_children'];
				} else {
					$base_price = $_product->get_price() * $values['quantity'];
					$line_price = $_product->get_price() * $values['quantity'];
				}

				// Tax data
				$taxes            = array();
				$discounted_taxes = array();

				/**
				 * No tax to calculate.
				 */
				if ( ! $_product->is_taxable() ) {

					// Discounted Price (price with any pre-tax discounts applied)
					$discounted_price  = $cart_object->get_discounted_price( $values, $base_price, true );
					$line_subtotal_tax = 0;
					$line_subtotal     = $line_price;
					$line_tax          = 0;
					$line_total        = round( $discounted_price, wc_get_rounding_precision() );

					/**
					 * Prices include tax.
					 */
				} elseif ( $cart_object->prices_include_tax ) {
					$base_tax_rates = $shop_tax_rates[$_product->tax_class];
					$item_tax_rates = $tax_rates[$_product->get_tax_class()];

					/**
					 * ADJUST TAX - Calculations when base tax is not equal to the item tax.
					 *
					 * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing with out of base locations.
					 * e.g. If a product costs 10 including tax, all users will pay 10 regardless of location and taxes.
					 * This feature is experimental @since 2.4.7 and may change in the future. Use at your risk.
					 */
					if ( $item_tax_rates !== $base_tax_rates && apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ) {

						// Work out a new base price without the shop's base tax
						$taxes = WC_Tax::calc_tax( $line_price, $base_tax_rates, true, true );

						// Now we have a new item price (excluding TAX)
						$line_subtotal     = round( $line_price - array_sum( $taxes ), wc_get_rounding_precision() );
						$taxes             = WC_Tax::calc_tax( $line_subtotal, $item_tax_rates );
						$line_subtotal_tax = array_sum( $taxes );

						// Adjusted price (this is the price including the new tax rate)
						$adjusted_price = ( $line_subtotal + $line_subtotal_tax ) / $values['quantity'];

						// Apply discounts and get the discounted price FOR A SINGLE ITEM
						$discounted_price = $cart_object->get_discounted_price( $values, $adjusted_price, true );

						// Convert back to line price and round nicely
						$discounted_line_price = round( $discounted_price * $values['quantity'], $cart_object->dp );

						// Now use rounded line price to get taxes.
						$discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true );
						$line_tax         = array_sum( $discounted_taxes );
						$line_total       = $discounted_line_price - $line_tax;

						/**
						 * Regular tax calculation (customer inside base and the tax class is unmodified.
						 */
					} else {

						// Work out a new base price without the item tax
						$taxes = WC_Tax::calc_tax( $line_price, $item_tax_rates, true );
						// Now we have a new item price (excluding TAX)
						$line_subtotal     = $line_price - array_sum( $taxes );
						$line_subtotal_tax = array_sum( $taxes );

						// Calc prices and tax (discounted)
						$discounted_price = $cart_object->get_discounted_price( $values, $base_price, true );

						// Convert back to line price and round nicely
						$discounted_line_price = round( $discounted_price, $cart_object->dp );

						// Now use rounded line price to get taxes.
						$discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true );
						$line_tax         = array_sum( $discounted_taxes );
						$line_total       = $discounted_line_price - $line_tax;
					}

					// Tax rows - merge the totals we just got
					foreach ( array_keys( $cart_object->taxes + $discounted_taxes ) as $key ) {
						$cart_object->taxes[$key] = ( isset( $discounted_taxes[$key] ) ? $discounted_taxes[$key] : 0 ) + ( isset( $cart_object->taxes[$key] ) ? $cart_object->taxes[$key] : 0 );
					}

					/**
					 * Prices exclude tax.
					 */
				} else {

					$item_tax_rates = $tax_rates[$_product->get_tax_class()];

					// Work out a new base price without the shop's base tax
					$taxes = WC_Tax::calc_tax( $line_price, $item_tax_rates );

					// Now we have the item price (excluding TAX)
					$line_subtotal     = $line_price;
					$line_subtotal_tax = array_sum( $taxes );

					// Now calc product rates
					$discounted_price      = $cart_object->get_discounted_price( $values, $base_price, true );
					$discounted_taxes      = WC_Tax::calc_tax( $discounted_price, $item_tax_rates );
					$discounted_tax_amount = array_sum( $discounted_taxes );
					$line_tax              = $discounted_tax_amount;
					$line_total            = $discounted_price;

					// Tax rows - merge the totals we just got
					foreach ( array_keys( $cart_object->taxes + $discounted_taxes ) as $key ) {
						$cart_object->taxes[$key] = ( isset( $discounted_taxes[$key] ) ? $discounted_taxes[$key] : 0 ) + ( isset( $cart_object->taxes[$key] ) ? $cart_object->taxes[$key] : 0 );
					}
				}

				// Cart contents total is based on discounted prices and is used for the final total calculation
				$cart_object->cart_contents_total += $line_total;

				// Store costs + taxes for lines
				$cart_object->cart_contents[$cart_item_key]['line_total']        = $line_total;
				$cart_object->cart_contents[$cart_item_key]['line_tax']          = $line_tax;
				$cart_object->cart_contents[$cart_item_key]['line_subtotal']     = $line_subtotal;
				$cart_object->cart_contents[$cart_item_key]['line_subtotal_tax'] = $line_subtotal_tax;

				// Store rates ID and costs - Since 2.2
				$cart_object->cart_contents[$cart_item_key]['line_tax_data'] = array(
					'total'    => $discounted_taxes,
					'subtotal' => $taxes
				);
			}

			// Only calculate the grand total + shipping if on the cart/checkout
			if ( is_checkout() || is_cart() || defined( 'WOOCOMMERCE_CHECKOUT' ) || defined( 'WOOCOMMERCE_CART' ) ) {

				// Calculate the Shipping
				$cart_object->calculate_shipping();

				// Trigger the fees API where developers can add fees to the cart
				$cart_object->calculate_fees();

				// Total up/round taxes and shipping taxes
				if ( $cart_object->round_at_subtotal ) {
					$cart_object->tax_total          = WC_Tax::get_tax_total( $cart_object->taxes );
					$cart_object->shipping_tax_total = WC_Tax::get_tax_total( $cart_object->shipping_taxes );
					$cart_object->taxes              = array_map( array( 'WC_Tax', 'round' ), $cart_object->taxes );
					$cart_object->shipping_taxes     = array_map(
						array(
							'WC_Tax',
							'round'
						), $cart_object->shipping_taxes
					);
				} else {
					$cart_object->tax_total          = array_sum( $cart_object->taxes );
					$cart_object->shipping_tax_total = array_sum( $cart_object->shipping_taxes );
				}

				// VAT exemption done at this point - so all totals are correct before exemption
				if ( WC()->customer->is_vat_exempt() ) {
					$cart_object->remove_taxes();
				}

				// Allow plugins to hook and alter totals before final total is calculated
				//			do_action( 'woocommerce_calculate_totals', $cart_object );

				// Grand Total - Discounted product prices, discounted tax, shipping cost + tax
				$cart_object->total = max( 0, apply_filters( 'woocommerce_calculated_total', round( $cart_object->cart_contents_total + $cart_object->tax_total + $cart_object->shipping_tax_total + $cart_object->shipping_total + $cart_object->fee_total, $cart_object->dp ), $cart_object ) );
			} else {

				// Set tax total to sum of all tax rows
				$cart_object->tax_total = WC_Tax::get_tax_total( $cart_object->taxes );

				// VAT exemption done at this point - so all totals are correct before exemption
				if ( WC()->customer->is_vat_exempt() ) {
					$cart_object->remove_taxes();
				}
			}
		} else {
			new Phys_Cart_Totals( $cart_object );
		}
	}

	public static function update_subtotal( $value, $cart_item ) {
		$value = wc_price( $cart_item['line_subtotal'] );

		return $value;
	}

	public static function notify_new_order() {
		$message = array( 'status' => 'error' );

		if ( isset( $_POST['limit'] ) ) {
			$limit = $_POST['limit'];
		} else {
			$message['status'] = 'error';
			wp_send_json( $message );
		}

		$args = array(
			'status'      => 'wc-completed',
			'type'        => wc_get_order_types( 'view-orders' ),
			'parent'      => null,
			'customer'    => null,
			'email'       => '',
			'limit'       => $limit,
			'offset'      => null,
			'exclude'     => array(),
			'orderby'     => 'rand',
			//'order'       => 'DESC',
			'return'      => 'objects',
			'paginate'    => false,
			'date_before' => '',
			'date_after'  => '',
		);

		$orders_tour = wc_get_orders( $args );

		$html = '';
		if ( count( $orders_tour ) > 0 ) {
			foreach ( $orders_tour as $order_tour ) {
				$items    = $order_tour->get_items();
				$key_item = array_keys( $items );
				$rand     = 0;
				if ( count( $key_item ) > 1 ) {
					$rand = rand( 0, count( $key_item ) - 1 );
				}
				$product = $items[$key_item[$rand]];
				$html    .= '<div class="item-order"><div class="inner-content"><a href="' . get_permalink( $product->get_product_id() ) . '">';
				$html    .= '<img src="' . get_the_post_thumbnail_url( $product->get_product_id(), 'thumbnail' ) . '" /></a>';
				$html    .= '<span>' . esc_html__( 'Someone in ', 'travel-booking' ) . $order_tour->get_billing_address_1() . ', ' . $order_tour->get_billing_city() . ', ' . $order_tour->get_billing_country() . esc_html__( ' purchased a ', 'travel-booking' ) . '</span>';
				$html    .= '<a href="' . get_permalink( $product->get_product_id() ) . '" class="title">' . $product->get_name() . '</a>';
				$html    .= '<span class="date">' . caculate_about_time( $order_tour->get_date_created() ) . '</span>';
				$html    .= '</div> </div>';
			}

			$message['status'] = 'success';
			$message['html']   = $html;
		}

		wp_send_json( $message );
	}
}

TravelPhysAjax::init();
